import * as Monaco from 'monaco-editor'
import { defineComponent, onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue'
import type { PropType, Ref } from 'vue'

import { createUseStyles } from 'vue-jss'

const useStyles = createUseStyles({
    container: {
        border: '1px solid black',
        display: 'flex',
        flexDirection: 'column',
        borderRadius: 5
    },
    title: {
        backgroundColor: '#eee',
        padding: '10px'
    },
    code: {
        flexGrow: 1,
    }
})

export default defineComponent({
    props: {
        code: {
            type: String as PropType<string>,
            require: true
        },
        onChange: {
            type: Function as PropType<(value: string, event: Monaco.editor.IModelContentChangedEvent) => void>,
            required: true,
        },
        title: {
            type: String as PropType<string>,
            require: true
        },
    },
    setup(props) {
        const editRef = shallowRef<Monaco.editor.IStandaloneCodeEditor>()
        const contentRef = ref()
        const classRef = useStyles()
        let _subscription: Monaco.IDisposable | undefined;
        let __prevent_triger_change_event = false
        onMounted(() => {
            const editor = editRef.value = Monaco.editor.create(contentRef.value, {
                value: props.code,
                language: 'json',
                formatOnPaste: true,
                tabSize: 2,
                minimap: {
                    enabled: true
                }
            })
            _subscription = editor.onDidChangeModelContent((event) => {
                // console.log('------->', __prevent_triger_change_event)
                if (!__prevent_triger_change_event) {
                    props.onChange(editor.getValue(), event)
                }
            })
        })
        watch(() => props.code, (v) => {
            const editor = editRef.value;
            if (editor) {
                const model = editor.getModel()
                if (v != model?.getValue()) {
                    editor.pushUndoStop()
                    __prevent_triger_change_event = true
                    model?.pushEditOperations([], [{
                        range: model.getFullModelRange(),
                        text: v as string
                    }], (res) => {
                        console.log(res)
                        return null
                    })
                    editor.popUndoStop()
                    __prevent_triger_change_event = false
                }
            }

        })
        onBeforeUnmount(() => {
            if (_subscription) {
                _subscription.dispose()
            }
        })

        return () => {
            const classes = classRef.value
            return (

                <div class={classes.container}>
                    <div class={classes.title}><span>{props.title}</span></div>
                    <div class={classes.code} ref={contentRef}></div>
                </div>
            )
        }
    }
})